pyscript-bootstrap-templates/pyscript_bootstrap_templates/cli_interface.py

212 lines
8.2 KiB
Python
Raw Normal View History

2022-07-24 11:58:11 +02:00
2022-09-11 16:33:43 +02:00
from distutils.command.config import config
from multiprocessing.sharedctypes import Value
2022-07-24 11:58:11 +02:00
import pathlib
from typing import List
import argparse
2022-09-11 16:33:43 +02:00
from numpy import isin
2022-07-24 18:46:10 +02:00
import requests
2022-09-11 16:33:43 +02:00
import json
import shutil
2022-07-24 11:58:11 +02:00
2022-07-24 18:46:10 +02:00
def download_file(url: str, path: pathlib.Path):
2022-09-11 16:33:43 +02:00
if pathlib.Path(url).exists():
shutil.copy2(url, str(path))
else:
response = requests.get(url)
path.write_bytes(response.content)
2022-07-24 18:46:10 +02:00
2022-07-24 11:58:11 +02:00
2022-09-11 16:33:43 +02:00
def generate_project_files(root_folder: pathlib.Path,
2022-07-24 11:58:11 +02:00
title: str,
packages: List[str],
paths: List[str] = None,
pyscript_css_url: str = "https://pyscript.net/alpha/pyscript.css",
2022-07-24 18:46:10 +02:00
pyscript_js_url: str = "https://pyscript.net/alpha/pyscript.min.js",
pyscript_py_url: str = "https://pyscript.net/alpha/pyscript.py",
bootstrap_css_url: str = "https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css",
bootstrap_js_url: str = "https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js",
pyscript_bootstrap_templates_wheel_url: str = "https://the-cake-is-a-lie.net/gogs/jonas/pyscript-bootstrap-templates/raw/branch/main/dist/pyscript_bootstrap_templates-0.1.0-py3-none-any.whl"):
2022-07-24 11:58:11 +02:00
2022-07-24 18:46:10 +02:00
pyenv = f"- ./resources/{pyscript_bootstrap_templates_wheel_url.split('/')[-1]}"
2022-07-24 11:58:11 +02:00
for package in packages:
pyenv += f"\n - {package}"
if paths is not None:
pyenv += "\n - paths:"
for path in paths:
pyenv += f"\n - {path}"
pyenv += "\n"
html = f"""
<!DOCTYPE html>
<html lang="en" style="width: 100%;height: 100%">
<head id="head">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
2022-09-11 10:42:04 +02:00
<link rel="stylesheet" href="./resources/pyscript.css" />
<script defer src="./resources/pyscript.js"></script>
2022-07-24 11:58:11 +02:00
<!-- Bootstrap CSS -->
2022-07-24 18:50:01 +02:00
<link href="./resources/bootstrap.css" rel="stylesheet">
2022-07-24 11:58:11 +02:00
<title>{title}</title>
2022-07-24 18:46:10 +02:00
2022-07-24 11:58:11 +02:00
<py-env>
{pyenv}
</py-env>
</head>
<body style="width: 100%; height: 100%">
2022-07-24 18:46:10 +02:00
<div id="pyscript_app" style="height: 100%; min-height: 100%"></div>
2022-07-24 11:58:11 +02:00
<py-script src="./main.py"></py-script>
2022-07-24 18:46:10 +02:00
<script src="./resources/bootstrap.js"></script>
2022-07-24 11:58:11 +02:00
</body>
</html>
"""
py = f"""
2022-07-24 18:46:10 +02:00
from pyscript_bootstrap_templates import bootstrap_templates
from pyscript_bootstrap_templates import bootstrap_HTML as bHTML
from pyscript_bootstrap_templates import HTML as HTML
app = bootstrap_templates.PyScriptBootstrapDashboard(
parent_element="pyscript_app", brand_name="{title}")
div = bHTML.BootstrapContainer("This is a sidebar", parent=app.sidebar)
div.font_size = 4
btn = bHTML.ButtonPrimary("Click me", parent=app.sidebar)
btn.w = 100
btn.onclick = lambda _: bHTML.AlertSuccess(
"You clicked me!", parent=app.main_area)
2022-07-24 11:58:11 +02:00
"""
2022-09-11 16:33:43 +02:00
root_folder=pathlib.Path(root_folder)
2022-07-24 18:46:10 +02:00
2022-09-11 16:33:43 +02:00
root_folder.mkdir(parents=True, exist_ok=True)
(root_folder / "resources").mkdir(parents=True, exist_ok=True)
2022-07-24 18:46:10 +02:00
# Download files:
download_file(pyscript_css_url, root_folder / "resources" / "pyscript.css")
download_file(pyscript_js_url, root_folder / "resources" / "pyscript.js")
download_file(pyscript_py_url, root_folder / "resources" / "pyscript.py")
download_file(bootstrap_css_url, root_folder /
"resources" / "bootstrap.css")
download_file(bootstrap_js_url, root_folder / "resources" / "bootstrap.js")
download_file(pyscript_bootstrap_templates_wheel_url,
root_folder / "resources" / pyscript_bootstrap_templates_wheel_url.split("/")[-1])
2022-07-24 11:58:11 +02:00
2022-09-11 16:33:43 +02:00
index_html = (root_folder / "index.html")
main_py = (root_folder / "main.py")
index_html.write_text(html, encoding="utf-8")
# only create if not existing:
if not main_py.exists():
main_py.write_text(py, encoding="utf-8")
2022-07-24 11:58:11 +02:00
2022-09-11 16:33:43 +02:00
def create_project(**kwargs):
root_folder: pathlib.Path = kwargs['root_folder']
if root_folder.exists():
raise ValueError(f"cannot create project. Folder {str(root_folder)} already exists")
root_folder.mkdir(parents=True, exist_ok=True)
# create initial config.json
kwargs['root_folder'] = str(root_folder)
with open(root_folder / "config.json", 'w') as f:
json.dump(kwargs, f, indent=4)
generate_project_files(**kwargs)
def update_project(**kwargs):
root_folder: pathlib.Path = kwargs['root_folder']
if not root_folder.exists():
raise ValueError(f"cannot update project in {str(root_folder)}. Path does not exist")
# load config file
config_json = root_folder / "config.json"
if not config_json.exists():
raise ValueError(f"cannot update project in {str(root_folder)}. Found no config.json inside give path")
with open(config_json, "r") as f:
config = json.load(f)
# override config values that are not None or empty lists
for arg, val in kwargs.items():
if val is not None:
if not isinstance(val, list) or len(val) > 0:
config[arg] = val
generate_project_files(**config)
config['root_folder'] = str(root_folder)
with open(root_folder / "config.json", 'w') as f:
json.dump(config, f, indent=4)
2022-07-24 11:58:11 +02:00
def main():
argument_parser = argparse.ArgumentParser(
description="create a new pyscript project")
2022-09-11 16:33:43 +02:00
argument_parser.add_argument("command", choices=["create","update"])
2022-07-24 11:58:11 +02:00
argument_parser.add_argument(
"root_folder", type=pathlib.Path, help="the root folder of the new project")
argument_parser.add_argument(
"title", type=str, help="the title of the new project")
argument_parser.add_argument(
2022-09-11 16:33:43 +02:00
"--packages", type=str, nargs="+", help="the packages to include in the new project")
2022-07-24 11:58:11 +02:00
argument_parser.add_argument("--paths", type=str, nargs="+",
help="additional local python files to include in the new project")
argument_parser.add_argument("--pyscript_css_url", type=str,
help="the url of the pyscript css file", default="https://pyscript.net/alpha/pyscript.css")
argument_parser.add_argument("--pyscript_js_url", type=str,
2022-07-24 18:46:10 +02:00
help="the url of the pyscript js file", default="https://pyscript.net/alpha/pyscript.min.js")
argument_parser.add_argument("--pyscript_py_url", type=str,
help="the url of the pyscript py file", default="https://pyscript.net/alpha/pyscript.py")
argument_parser.add_argument("--bootstrap_css_url", type=str,
help="the url of the bootstrap css file", default="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css")
argument_parser.add_argument("--bootstrap_js_url", type=str,
help="the url of the bootstrap js file", default="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js")
argument_parser.add_argument("--pyscript_bootstrap_templates_wheel_url", type=str,
help="the url of the pyscript bootstrap templates wheel file", default="https://the-cake-is-a-lie.net/gogs/jonas/pyscript-bootstrap-templates/raw/branch/main/dist/pyscript_bootstrap_templates-0.1.0-py3-none-any.whl")
args = argument_parser.parse_args()
2022-07-24 11:58:11 +02:00
2022-09-11 16:33:43 +02:00
config = {
'root_folder': args.root_folder,
'title': args.title,
'packages': args.packages if args.packages is not None else [],
'paths': args.paths if args.paths is not None else [],
'pyscript_css_url': args.pyscript_css_url,
'pyscript_js_url': args.pyscript_js_url,
'pyscript_py_url': args.pyscript_py_url,
'bootstrap_css_url': args.bootstrap_css_url,
'bootstrap_js_url': args.bootstrap_js_url,
'pyscript_bootstrap_templates_wheel_url': args.pyscript_bootstrap_templates_wheel_url
}
if args.command == "create":
create_project(**config)
elif args.command == "update":
update_project(**config)
else:
# should never happen and be catched by argparse#
raise ValueError("unknown command", args.command)
2022-07-24 11:58:11 +02:00
if __name__ == "__main__":
main()
2022-07-24 18:46:10 +02:00
exit(0)