instaui 0.1.4__py3-none-any.whl → 0.1.6__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- instaui/arco/__init__.py +191 -0
- instaui/arco/_settings.py +25 -0
- instaui/arco/_use_tools/locale.py +50 -0
- instaui/arco/component_types.py +1019 -0
- instaui/arco/components/_utils.py +22 -0
- instaui/arco/components/affix.py +29 -0
- instaui/arco/components/alert.py +42 -0
- instaui/arco/components/anchor.py +42 -0
- instaui/arco/components/auto_complete.py +96 -0
- instaui/arco/components/avatar.py +55 -0
- instaui/arco/components/back_top.py +14 -0
- instaui/arco/components/badge.py +14 -0
- instaui/arco/components/breadcrumb.py +14 -0
- instaui/arco/components/button.py +43 -0
- instaui/arco/components/calendar.py +47 -0
- instaui/arco/components/card.py +14 -0
- instaui/arco/components/carousel.py +33 -0
- instaui/arco/components/cascader.py +111 -0
- instaui/arco/components/checkbox.py +32 -0
- instaui/arco/components/collapse.py +31 -0
- instaui/arco/components/color_picker.py +45 -0
- instaui/arco/components/comment.py +14 -0
- instaui/arco/components/config_provider.py +13 -0
- instaui/arco/components/date_picker.py +111 -0
- instaui/arco/components/descriptions.py +14 -0
- instaui/arco/components/divider.py +13 -0
- instaui/arco/components/drawer.py +98 -0
- instaui/arco/components/dropdown.py +45 -0
- instaui/arco/components/empty.py +14 -0
- instaui/arco/components/form.py +55 -0
- instaui/arco/components/icon.py +17 -0
- instaui/arco/components/image.py +33 -0
- instaui/arco/components/input.py +102 -0
- instaui/arco/components/input_number.py +97 -0
- instaui/arco/components/input_password.py +38 -0
- instaui/arco/components/input_search.py +37 -0
- instaui/arco/components/input_tag.py +110 -0
- instaui/arco/components/layout.py +13 -0
- instaui/arco/components/layout_content.py +6 -0
- instaui/arco/components/layout_footer.py +6 -0
- instaui/arco/components/layout_header.py +6 -0
- instaui/arco/components/layout_sider.py +53 -0
- instaui/arco/components/link.py +36 -0
- instaui/arco/components/list.py +68 -0
- instaui/arco/components/mention.py +97 -0
- instaui/arco/components/menu.py +88 -0
- instaui/arco/components/modal.py +97 -0
- instaui/arco/components/overflow_list.py +29 -0
- instaui/arco/components/page_header.py +29 -0
- instaui/arco/components/pagination.py +45 -0
- instaui/arco/components/pop_confirm.py +58 -0
- instaui/arco/components/popover.py +32 -0
- instaui/arco/components/progress.py +14 -0
- instaui/arco/components/radio.py +40 -0
- instaui/arco/components/radio_group.py +42 -0
- instaui/arco/components/rate.py +45 -0
- instaui/arco/components/resize_box.py +62 -0
- instaui/arco/components/result.py +14 -0
- instaui/arco/components/select.py +179 -0
- instaui/arco/components/skeleton.py +14 -0
- instaui/arco/components/slider.py +38 -0
- instaui/arco/components/space.py +14 -0
- instaui/arco/components/spin.py +14 -0
- instaui/arco/components/split.py +76 -0
- instaui/arco/components/statistic.py +14 -0
- instaui/arco/components/steps.py +32 -0
- instaui/arco/components/switch.py +57 -0
- instaui/arco/components/tab_pane.py +12 -0
- instaui/arco/components/table.py +276 -0
- instaui/arco/components/tabs.py +101 -0
- instaui/arco/components/tag.py +42 -0
- instaui/arco/components/textarea.py +84 -0
- instaui/arco/components/time_picker.py +76 -0
- instaui/arco/components/timeline.py +14 -0
- instaui/arco/components/tooltip.py +29 -0
- instaui/arco/components/transfer.py +58 -0
- instaui/arco/components/tree.py +120 -0
- instaui/arco/components/tree_select.py +86 -0
- instaui/arco/components/trigger.py +58 -0
- instaui/arco/components/typography.py +142 -0
- instaui/arco/components/upload.py +71 -0
- instaui/arco/components/verification_code.py +58 -0
- instaui/arco/components/watermark.py +14 -0
- instaui/arco/locales/__init__.py +4 -0
- instaui/arco/locales/_index.py +31 -0
- instaui/arco/locales/en_us.py +227 -0
- instaui/arco/locales/zh_cn.py +224 -0
- instaui/arco/setup.py +36 -0
- instaui/arco/static/instaui-arco.css +1 -0
- instaui/arco/static/instaui-arco.js +55771 -0
- instaui/arco/types.py +24 -0
- instaui/components/column.py +10 -2
- instaui/components/echarts/echarts.js +128 -0
- instaui/components/echarts/echarts.py +194 -0
- instaui/components/echarts/static/echarts.esm.min.js +45 -0
- instaui/components/element.py +50 -6
- instaui/components/grid.py +81 -0
- instaui/components/html/__init__.py +30 -19
- instaui/components/html/_preset.py +4 -0
- instaui/components/html/heading.py +51 -0
- instaui/components/html/range.py +3 -0
- instaui/components/html/select.py +13 -31
- instaui/components/html/table.py +36 -0
- instaui/components/markdown/static/github-markdown.css +1 -1
- instaui/components/markdown/static/marked.esm.js +0 -1
- instaui/components/row.py +8 -7
- instaui/components/shiki_code/shiki_code.js +126 -0
- instaui/components/shiki_code/shiki_code.py +99 -0
- instaui/components/shiki_code/static/langs/css.mjs +5 -0
- instaui/components/shiki_code/static/langs/markdown.mjs +5 -0
- instaui/components/shiki_code/static/langs/python.mjs +5 -0
- instaui/components/shiki_code/static/langs/shell.mjs +2 -0
- instaui/components/shiki_code/static/langs/shellscript.mjs +5 -0
- instaui/components/shiki_code/static/shiki-core.js +5784 -0
- instaui/components/shiki_code/static/shiki-style.css +179 -0
- instaui/components/shiki_code/static/shiki-transformers.js +461 -0
- instaui/components/shiki_code/static/themes/vitesse-dark.mjs +2 -0
- instaui/components/shiki_code/static/themes/vitesse-light.mjs +2 -0
- instaui/components/value_element.py +7 -3
- instaui/consts.py +2 -1
- instaui/event/js_event.py +1 -0
- instaui/event/web_event.py +6 -7
- instaui/experimental/link_sql/__init__.py +3 -0
- instaui/experimental/link_sql/_base.py +23 -0
- instaui/experimental/link_sql/_duckdb.py +221 -0
- instaui/experimental/link_sql/_types.py +15 -0
- instaui/experimental/link_sql/data_source.js +50 -0
- instaui/fastapi_server/debug_mode_router.py +1 -1
- instaui/fastapi_server/server.py +4 -12
- instaui/handlers/event_handler.py +3 -1
- instaui/handlers/watch_handler.py +4 -0
- instaui/html_tools.py +41 -4
- instaui/runtime/_app.py +37 -3
- instaui/runtime/_link_manager.py +89 -0
- instaui/runtime/resource.py +19 -9
- instaui/runtime/scope.py +28 -7
- instaui/shadcn_classless/_index.py +42 -0
- instaui/shadcn_classless/static/shadcn-classless.css +403 -0
- instaui/static/insta-ui.css +1 -1
- instaui/static/insta-ui.esm-browser.prod.js +3663 -3658
- instaui/static/insta-ui.js.map +1 -1
- instaui/static/instaui-tools-browser.js +511 -0
- instaui/static/templates/debug/sse.html +1 -1
- instaui/static/templates/webview.html +78 -0
- instaui/tailwind/__init__.py +6 -0
- instaui/tailwind/_index.py +24 -0
- instaui/{static/tailwindcss.min.js → tailwind/static/tailwindcss-v3.min.js} +62 -62
- instaui/tailwind/static/tailwindcss-v4.min.js +8 -0
- instaui/template/_utils.py +23 -0
- instaui/template/webview_template.py +50 -0
- instaui/ui/__init__.py +8 -2
- instaui/ui/__init__.pyi +7 -1
- instaui/ui_functions/ui_page.py +1 -1
- instaui/vars/data.py +7 -7
- instaui/vars/element_ref.py +2 -4
- instaui/vars/event_context.py +4 -0
- instaui/vars/js_computed.py +6 -8
- instaui/vars/ref.py +6 -6
- instaui/vars/vue_computed.py +6 -7
- instaui/vars/web_computed.py +31 -32
- instaui/watch/vue_watch.py +23 -7
- instaui/watch/web_watch.py +5 -6
- instaui/webview/__init__.py +1 -0
- instaui/webview/_utils.py +8 -0
- instaui/webview/api.py +72 -0
- instaui/webview/func.py +114 -0
- instaui/webview/index.py +162 -0
- instaui/webview/resource.py +172 -0
- instaui/zero/func.py +19 -12
- instaui/zero/scope.py +29 -28
- {instaui-0.1.4.dist-info → instaui-0.1.6.dist-info}/METADATA +6 -2
- instaui-0.1.6.dist-info/RECORD +286 -0
- instaui/components/highlight_code/code.js +0 -63
- instaui/components/highlight_code/code.py +0 -117
- instaui/components/highlight_code/static/core.min.js +0 -307
- instaui/components/highlight_code/static/languages/css.min.js +0 -31
- instaui/components/highlight_code/static/languages/javascript.min.js +0 -81
- instaui/components/highlight_code/static/languages/json.min.js +0 -8
- instaui/components/highlight_code/static/languages/python-repl.min.js +0 -5
- instaui/components/highlight_code/static/languages/python.min.js +0 -42
- instaui/components/highlight_code/static/languages/shell.min.js +0 -5
- instaui/components/highlight_code/static/styles/default.min.css +0 -9
- instaui/components/highlight_code/static/styles/github-dark-dimmed.min.css +0 -9
- instaui/components/highlight_code/static/styles/github-dark.min.css +0 -10
- instaui/components/highlight_code/static/styles/github.min.css +0 -10
- instaui/daisyui/__init__.py +0 -20
- instaui/daisyui/_index.py +0 -15
- instaui/daisyui/button.py +0 -38
- instaui/daisyui/checkbox.py +0 -17
- instaui/daisyui/static/daisyui.css +0 -1
- instaui/daisyui/static/themes.css +0 -1
- instaui/handlers/computed_handler.py +0 -42
- instaui/handlers/config_handler.py +0 -13
- instaui/ui/__build_init.py +0 -73
- instaui/vars/_utils.py +0 -12
- instaui-0.1.4.dist-info/RECORD +0 -179
- {instaui-0.1.4.dist-info → instaui-0.1.6.dist-info}/LICENSE +0 -0
- {instaui-0.1.4.dist-info → instaui-0.1.6.dist-info}/WHEEL +0 -0
instaui/webview/func.py
ADDED
@@ -0,0 +1,114 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
import itertools
|
3
|
+
from pathlib import Path
|
4
|
+
import instaui.consts as consts
|
5
|
+
from instaui.runtime._app import get_app_slot, get_default_app_slot
|
6
|
+
from instaui.template import render_zero_html
|
7
|
+
from instaui.template import zero_template
|
8
|
+
from instaui.html_tools import to_config_data
|
9
|
+
from instaui.runtime.dataclass import JsLink
|
10
|
+
from instaui.runtime.resource import HtmlResource
|
11
|
+
|
12
|
+
|
13
|
+
def get_template_model():
|
14
|
+
system_slot = get_app_slot()
|
15
|
+
|
16
|
+
merge_global_resources = (system_slot.meta or {}).get(
|
17
|
+
"merge_global_resources", True
|
18
|
+
)
|
19
|
+
|
20
|
+
default_app_slot = get_default_app_slot()
|
21
|
+
html_resource = system_slot._html_resource
|
22
|
+
default_html_resource = (
|
23
|
+
default_app_slot._html_resource
|
24
|
+
if merge_global_resources
|
25
|
+
else _empty_html_resource()
|
26
|
+
)
|
27
|
+
|
28
|
+
config_data = to_config_data()
|
29
|
+
|
30
|
+
model = zero_template.ZeroTemplateModel(
|
31
|
+
vue_js_code=consts.VUE_ES_JS_PATH,
|
32
|
+
instaui_js_code=consts.APP_ES_JS_PATH,
|
33
|
+
css_links=[
|
34
|
+
consts.APP_CSS_PATH,
|
35
|
+
],
|
36
|
+
config_dict=config_data,
|
37
|
+
favicon=html_resource.favicon
|
38
|
+
or default_html_resource.favicon
|
39
|
+
or consts.FAVICON_PATH,
|
40
|
+
title=html_resource.title or default_html_resource.title or consts.PAGE_TITLE,
|
41
|
+
)
|
42
|
+
|
43
|
+
# register custom components
|
44
|
+
for component in system_slot._component_dependencies:
|
45
|
+
if not component.esm:
|
46
|
+
continue
|
47
|
+
|
48
|
+
model.vue_app_component.append(
|
49
|
+
zero_template.ZeroVueAppComponent(
|
50
|
+
name=component.tag_name,
|
51
|
+
url=component.esm,
|
52
|
+
)
|
53
|
+
)
|
54
|
+
|
55
|
+
if component.css:
|
56
|
+
for css_link in component.css:
|
57
|
+
model.css_links.append(css_link)
|
58
|
+
|
59
|
+
if component.externals:
|
60
|
+
for name, url in component.externals.items():
|
61
|
+
if url.is_file():
|
62
|
+
model.add_extra_import_map(name, url)
|
63
|
+
|
64
|
+
# register custom plugins
|
65
|
+
for plugin in set(
|
66
|
+
itertools.chain(
|
67
|
+
system_slot._plugin_dependencies, default_app_slot._plugin_dependencies
|
68
|
+
)
|
69
|
+
):
|
70
|
+
if not plugin.esm:
|
71
|
+
continue
|
72
|
+
|
73
|
+
model.vue_app_use.append(plugin.name)
|
74
|
+
|
75
|
+
model.add_extra_import_map(plugin.name, plugin.esm)
|
76
|
+
|
77
|
+
if plugin.css:
|
78
|
+
for css_link in plugin.css:
|
79
|
+
model.css_links.append(css_link)
|
80
|
+
|
81
|
+
# css file link to web static link
|
82
|
+
for link in html_resource.get_valid_css_links(
|
83
|
+
default_html_resource._css_links_manager
|
84
|
+
):
|
85
|
+
if isinstance(link, Path):
|
86
|
+
model.css_links.append(link)
|
87
|
+
|
88
|
+
# js file link to web static link
|
89
|
+
for info in html_resource.get_valid_js_links(
|
90
|
+
default_html_resource._js_links_manager
|
91
|
+
):
|
92
|
+
if isinstance(info.link, Path):
|
93
|
+
model.js_links.append(JsLink(info.link))
|
94
|
+
|
95
|
+
for js_code in itertools.chain(
|
96
|
+
html_resource._script_tags, default_html_resource._script_tags
|
97
|
+
):
|
98
|
+
model.script_tags.append(js_code)
|
99
|
+
|
100
|
+
for sylte_code in itertools.chain(
|
101
|
+
html_resource._style_tags, default_html_resource._style_tags
|
102
|
+
):
|
103
|
+
model.style_tags.append(sylte_code)
|
104
|
+
|
105
|
+
return model
|
106
|
+
|
107
|
+
|
108
|
+
def to_html_str():
|
109
|
+
model = get_template_model()
|
110
|
+
return render_zero_html(model)
|
111
|
+
|
112
|
+
|
113
|
+
def _empty_html_resource():
|
114
|
+
return HtmlResource()
|
instaui/webview/index.py
ADDED
@@ -0,0 +1,162 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
from contextlib import contextmanager
|
3
|
+
from pathlib import Path
|
4
|
+
import shutil
|
5
|
+
from typing import Any, Callable, Dict, Iterable, List, Optional, Union
|
6
|
+
from typing_extensions import TypedDict, Unpack
|
7
|
+
import webview
|
8
|
+
import webview.http as http
|
9
|
+
from webview.guilib import GUIType
|
10
|
+
|
11
|
+
from instaui.runtime._app import get_app_slot, new_app_slot, reset_app_slot
|
12
|
+
from instaui.launch_collector import get_launch_collector
|
13
|
+
|
14
|
+
from . import resource
|
15
|
+
from . import api
|
16
|
+
from . import _utils
|
17
|
+
|
18
|
+
|
19
|
+
class WebviewWrapper:
|
20
|
+
"""Example usage:
|
21
|
+
.. code-block:: python
|
22
|
+
from instaui import ui
|
23
|
+
|
24
|
+
@ui.page("/")
|
25
|
+
def index_page():
|
26
|
+
ui.content("Hello, world!")
|
27
|
+
|
28
|
+
ui.webview().run()
|
29
|
+
"""
|
30
|
+
|
31
|
+
def __init__(
|
32
|
+
self,
|
33
|
+
*,
|
34
|
+
assets_path: Union[str, Path] = "./webview_assets",
|
35
|
+
debug: bool = False,
|
36
|
+
auto_create_window: Union[bool, str] = "/",
|
37
|
+
on_app_mounted: Optional[Callable] = None,
|
38
|
+
) -> None:
|
39
|
+
"""Create a new webview wrapper.
|
40
|
+
|
41
|
+
Args:
|
42
|
+
assets_path (Union[str, Path], optional): Path to store assets. Defaults to "./webview_assets".
|
43
|
+
debug (bool, optional): Whether to run in debug mode. Defaults to False.
|
44
|
+
auto_create_window (Union[bool, str], optional): Whether to create a window automatically. If a string is provided, it will be used as the initial page URL. Defaults to "/".
|
45
|
+
testing (bool, optional): Whether to run in testing mode. Defaults to False.
|
46
|
+
"""
|
47
|
+
|
48
|
+
self.assets_path = (
|
49
|
+
Path(self._get_assets_path(assets_path))
|
50
|
+
if isinstance(assets_path, str)
|
51
|
+
else assets_path
|
52
|
+
)
|
53
|
+
_utils.reset_dir(self.assets_path)
|
54
|
+
self.debug = debug
|
55
|
+
self.on_app_mounted = on_app_mounted
|
56
|
+
|
57
|
+
self._auto_create_window = auto_create_window
|
58
|
+
|
59
|
+
def create_window(
|
60
|
+
self,
|
61
|
+
page_url: str = "/",
|
62
|
+
):
|
63
|
+
"""Create a new window. Returns the window object of pywebview.
|
64
|
+
|
65
|
+
Args:
|
66
|
+
page_url (str, optional): Page URL to load. Defaults to "/".
|
67
|
+
|
68
|
+
"""
|
69
|
+
launch_collector = get_launch_collector()
|
70
|
+
with _scope():
|
71
|
+
app = get_app_slot()
|
72
|
+
app._page_path = page_url
|
73
|
+
page_info = launch_collector._page_router[page_url]
|
74
|
+
page_info.func()
|
75
|
+
|
76
|
+
resource_info = resource.resource_to_assets(
|
77
|
+
page_url=page_url,
|
78
|
+
assets_path=self.assets_path,
|
79
|
+
on_app_mounted=self.on_app_mounted,
|
80
|
+
)
|
81
|
+
|
82
|
+
window = webview.create_window(
|
83
|
+
resource_info.title, resource_info.index_html_url, js_api=api.Api()
|
84
|
+
)
|
85
|
+
|
86
|
+
if self.on_app_mounted:
|
87
|
+
|
88
|
+
def on_app_mounted():
|
89
|
+
self.on_app_mounted(window) # type: ignore
|
90
|
+
|
91
|
+
window.expose(on_app_mounted)
|
92
|
+
|
93
|
+
return window
|
94
|
+
|
95
|
+
def run(self, **webview_start_args: Unpack[WebviewStartArgs]):
|
96
|
+
"""Run the webview.
|
97
|
+
|
98
|
+
Args:
|
99
|
+
:param func: Function to invoke upon starting the GUI loop.
|
100
|
+
:param args: Function arguments. Can be either a single value or a tuple of
|
101
|
+
values.
|
102
|
+
:param localization: A dictionary with localized strings. Default strings
|
103
|
+
and their keys are defined in localization.py.
|
104
|
+
:param gui: Force a specific GUI. Allowed values are ``cef``, ``qt``,
|
105
|
+
``gtk``, ``mshtml`` or ``edgechromium`` depending on a platform.
|
106
|
+
:param http_server: Enable built-in HTTP server. If enabled, local files
|
107
|
+
will be served using a local HTTP server on a random port. For each
|
108
|
+
window, a separate HTTP server is spawned. This option is ignored for
|
109
|
+
non-local URLs.
|
110
|
+
:param user_agent: Change user agent string.
|
111
|
+
:param private_mode: Enable private mode. In private mode, cookies and local storage are not preserved.
|
112
|
+
Default is True.
|
113
|
+
:param storage_path: Custom location for cookies and other website data
|
114
|
+
:param menu: List of menus to be included in the app menu
|
115
|
+
:param server: Server class. Defaults to BottleServer
|
116
|
+
:param server_args: Dictionary of arguments to pass through to the server instantiation
|
117
|
+
:param ssl: Enable SSL for local HTTP server. Default is False.
|
118
|
+
:param icon: Path to the icon file. Supported only on GTK/QT.
|
119
|
+
"""
|
120
|
+
|
121
|
+
if self._auto_create_window:
|
122
|
+
self.create_window(
|
123
|
+
"/" if self._auto_create_window is True else self._auto_create_window
|
124
|
+
)
|
125
|
+
|
126
|
+
webview.start(**webview_start_args, debug=self.debug)
|
127
|
+
|
128
|
+
@staticmethod
|
129
|
+
def _get_assets_path(file: Union[str, Path]) -> Path:
|
130
|
+
if isinstance(file, str):
|
131
|
+
import inspect
|
132
|
+
|
133
|
+
frame = inspect.currentframe().f_back.f_back.f_back # type: ignore
|
134
|
+
assert frame is not None
|
135
|
+
script_file = inspect.getfile(frame)
|
136
|
+
file = Path(script_file).parent.joinpath(file)
|
137
|
+
|
138
|
+
return file
|
139
|
+
|
140
|
+
|
141
|
+
@contextmanager
|
142
|
+
def _scope():
|
143
|
+
token = new_app_slot("webview")
|
144
|
+
yield
|
145
|
+
reset_app_slot(token)
|
146
|
+
|
147
|
+
|
148
|
+
class WebviewStartArgs(TypedDict, total=False):
|
149
|
+
func: Union[Callable[..., None], None]
|
150
|
+
args: Union[Iterable[Any], None]
|
151
|
+
localization: Dict[str, str]
|
152
|
+
gui: Union[GUIType, None]
|
153
|
+
http_server: bool
|
154
|
+
http_port: Union[int, None]
|
155
|
+
user_agent: Union[str, None]
|
156
|
+
private_mode: bool
|
157
|
+
storage_path: Union[str, None]
|
158
|
+
menu: List[Any]
|
159
|
+
server: type[http.ServerType] # type: ignore
|
160
|
+
server_args: Dict[Any, Any]
|
161
|
+
ssl: bool
|
162
|
+
icon: Union[str, None]
|
@@ -0,0 +1,172 @@
|
|
1
|
+
from dataclasses import dataclass
|
2
|
+
import itertools
|
3
|
+
from pathlib import Path
|
4
|
+
import shutil
|
5
|
+
from typing import Callable, Optional
|
6
|
+
from urllib.parse import quote
|
7
|
+
|
8
|
+
from instaui.html_tools import to_config_data
|
9
|
+
from instaui.runtime._app import get_app_slot, get_default_app_slot
|
10
|
+
from instaui.systems import file_system
|
11
|
+
from instaui.template import webview_template
|
12
|
+
from instaui import consts
|
13
|
+
|
14
|
+
from . import _utils
|
15
|
+
|
16
|
+
|
17
|
+
_INDEX_HTML_NAME = "index.html"
|
18
|
+
|
19
|
+
|
20
|
+
@dataclass
|
21
|
+
class ResourceInfo:
|
22
|
+
title: str
|
23
|
+
index_html_url: str
|
24
|
+
|
25
|
+
|
26
|
+
def resource_to_assets(
|
27
|
+
page_url: str, assets_path: Path, on_app_mounted: Optional[Callable] = None
|
28
|
+
):
|
29
|
+
page_dir = assets_path.joinpath(quote(page_url, safe=""))
|
30
|
+
_utils.reset_dir(page_dir)
|
31
|
+
|
32
|
+
relative_to_assets = _get_relative_to_assets(page_dir)
|
33
|
+
file_to_assets = _get_file_to_assets(page_dir)
|
34
|
+
|
35
|
+
config_data = to_config_data()
|
36
|
+
|
37
|
+
system_slot = get_app_slot()
|
38
|
+
default_app_slot = get_default_app_slot()
|
39
|
+
html_resource = system_slot._html_resource
|
40
|
+
default_html_resource = default_app_slot._html_resource
|
41
|
+
|
42
|
+
if html_resource.favicon:
|
43
|
+
favicon_url = file_to_assets(html_resource.favicon)
|
44
|
+
else:
|
45
|
+
if default_html_resource.favicon:
|
46
|
+
favicon_url = file_to_assets(default_html_resource.favicon)
|
47
|
+
else:
|
48
|
+
favicon_url = file_to_assets(consts.FAVICON_PATH)
|
49
|
+
|
50
|
+
model = webview_template.WebViewTemplateModel(
|
51
|
+
vue_js_code=file_to_assets(consts.VUE_ES_JS_PATH),
|
52
|
+
instaui_js_code=file_to_assets(consts.APP_ES_JS_PATH),
|
53
|
+
css_links=[
|
54
|
+
file_to_assets(consts.APP_CSS_PATH),
|
55
|
+
],
|
56
|
+
config_dict=config_data,
|
57
|
+
favicon_url=favicon_url,
|
58
|
+
title=html_resource.title or default_html_resource.title or consts.PAGE_TITLE,
|
59
|
+
on_app_mounted=on_app_mounted,
|
60
|
+
)
|
61
|
+
|
62
|
+
# register custom components
|
63
|
+
for component in system_slot._component_dependencies:
|
64
|
+
if not component.esm:
|
65
|
+
continue
|
66
|
+
|
67
|
+
component_url = file_to_assets(component.esm)
|
68
|
+
model.add_extra_import_map(component_url, file_to_assets(component.esm))
|
69
|
+
|
70
|
+
model.vue_app_component.append(
|
71
|
+
webview_template.WebViewVueAppComponent(
|
72
|
+
name=component.tag_name,
|
73
|
+
url=component_url,
|
74
|
+
)
|
75
|
+
)
|
76
|
+
|
77
|
+
if component.css:
|
78
|
+
for css_link in component.css:
|
79
|
+
css_resource = file_to_assets(css_link)
|
80
|
+
if css_link.is_file():
|
81
|
+
model.css_links.append(css_resource)
|
82
|
+
|
83
|
+
if component.externals:
|
84
|
+
for name, file in component.externals.items():
|
85
|
+
model.add_extra_import_map(name, file_to_assets(file))
|
86
|
+
|
87
|
+
# register custom plugins
|
88
|
+
for plugin in set(
|
89
|
+
itertools.chain(
|
90
|
+
system_slot._plugin_dependencies, default_app_slot._plugin_dependencies
|
91
|
+
)
|
92
|
+
):
|
93
|
+
if not plugin.esm:
|
94
|
+
continue
|
95
|
+
|
96
|
+
model.vue_app_use.append(plugin.name)
|
97
|
+
|
98
|
+
model.add_extra_import_map(plugin.name, file_to_assets(plugin.esm))
|
99
|
+
|
100
|
+
if plugin.css:
|
101
|
+
for css_link in plugin.css:
|
102
|
+
model.css_links.append(file_to_assets(css_link))
|
103
|
+
|
104
|
+
# css file link to web static link
|
105
|
+
for link in html_resource.get_valid_css_links(
|
106
|
+
default_html_resource._css_links_manager
|
107
|
+
):
|
108
|
+
if isinstance(link, Path):
|
109
|
+
model.css_links.append(file_to_assets(link))
|
110
|
+
else:
|
111
|
+
model.css_links.append(link)
|
112
|
+
|
113
|
+
# js file link to web static link
|
114
|
+
for info in html_resource.get_valid_js_links(
|
115
|
+
default_html_resource._js_links_manager
|
116
|
+
):
|
117
|
+
link = file_to_assets(info.link) if isinstance(info.link, Path) else info.link
|
118
|
+
model.js_links.append(link)
|
119
|
+
|
120
|
+
for js_code in itertools.chain(
|
121
|
+
html_resource._script_tags, default_html_resource._script_tags
|
122
|
+
):
|
123
|
+
model.script_tags.append(js_code)
|
124
|
+
|
125
|
+
for sylte_code in itertools.chain(
|
126
|
+
html_resource._style_tags, default_html_resource._style_tags
|
127
|
+
):
|
128
|
+
model.style_tags.append(sylte_code)
|
129
|
+
|
130
|
+
html_str = webview_template.render_wbeview_html(model)
|
131
|
+
|
132
|
+
index_html_path = page_dir / _INDEX_HTML_NAME
|
133
|
+
index_html_path.write_text(html_str, encoding="utf-8")
|
134
|
+
relative_to_assets(index_html_path)
|
135
|
+
index_html_url = str(index_html_path.absolute())
|
136
|
+
return ResourceInfo(
|
137
|
+
title="test",
|
138
|
+
index_html_url=index_html_url,
|
139
|
+
)
|
140
|
+
|
141
|
+
|
142
|
+
def _get_relative_to_assets(assets_path: Path):
|
143
|
+
def wrapper(file_path: Path, relative_parent=False):
|
144
|
+
return str(
|
145
|
+
file_path.relative_to(
|
146
|
+
assets_path.parent if relative_parent else assets_path
|
147
|
+
)
|
148
|
+
).replace("\\", "/")
|
149
|
+
|
150
|
+
return wrapper
|
151
|
+
|
152
|
+
|
153
|
+
def _get_file_to_assets(assets_path: Path):
|
154
|
+
relative_to_assets = _get_relative_to_assets(assets_path)
|
155
|
+
|
156
|
+
def wrapper(file_path: Path):
|
157
|
+
hash_part = file_system.generate_hash_name_from_path(file_path.parent)
|
158
|
+
new_folder_path = assets_path.joinpath(hash_part)
|
159
|
+
|
160
|
+
if not new_folder_path.exists():
|
161
|
+
new_folder_path.mkdir(parents=True)
|
162
|
+
|
163
|
+
new_path = new_folder_path.joinpath(file_path.name)
|
164
|
+
|
165
|
+
if file_path.is_file():
|
166
|
+
shutil.copyfile(file_path, new_path)
|
167
|
+
return "./" + relative_to_assets(new_path)
|
168
|
+
else:
|
169
|
+
shutil.copytree(file_path, new_path, dirs_exist_ok=True)
|
170
|
+
return "./" + relative_to_assets(new_path) + "/"
|
171
|
+
|
172
|
+
return wrapper
|
instaui/zero/func.py
CHANGED
@@ -7,6 +7,7 @@ from instaui.template import render_zero_html
|
|
7
7
|
from instaui.template import zero_template
|
8
8
|
from instaui.html_tools import to_config_data
|
9
9
|
from instaui.runtime.dataclass import JsLink
|
10
|
+
from instaui.runtime.resource import HtmlResource
|
10
11
|
|
11
12
|
|
12
13
|
def to_html(file: Path):
|
@@ -20,9 +21,18 @@ def to_html(file: Path):
|
|
20
21
|
|
21
22
|
def get_template_model():
|
22
23
|
system_slot = get_app_slot()
|
24
|
+
|
25
|
+
merge_global_resources = (system_slot.meta or {}).get(
|
26
|
+
"merge_global_resources", True
|
27
|
+
)
|
28
|
+
|
23
29
|
default_app_slot = get_default_app_slot()
|
24
30
|
html_resource = system_slot._html_resource
|
25
|
-
default_html_resource =
|
31
|
+
default_html_resource = (
|
32
|
+
default_app_slot._html_resource
|
33
|
+
if merge_global_resources
|
34
|
+
else _empty_html_resource()
|
35
|
+
)
|
26
36
|
|
27
37
|
config_data = to_config_data()
|
28
38
|
|
@@ -39,13 +49,6 @@ def get_template_model():
|
|
39
49
|
title=html_resource.title or default_html_resource.title or consts.PAGE_TITLE,
|
40
50
|
)
|
41
51
|
|
42
|
-
if html_resource.use_tailwind is None:
|
43
|
-
if default_html_resource.use_tailwind:
|
44
|
-
model.js_links.append(JsLink(consts.TAILWIND_JS_PATH))
|
45
|
-
else:
|
46
|
-
if html_resource.use_tailwind:
|
47
|
-
model.js_links.append(JsLink(consts.TAILWIND_JS_PATH))
|
48
|
-
|
49
52
|
# register custom components
|
50
53
|
for component in system_slot._component_dependencies:
|
51
54
|
if not component.esm:
|
@@ -85,15 +88,15 @@ def get_template_model():
|
|
85
88
|
model.css_links.append(css_link)
|
86
89
|
|
87
90
|
# css file link to web static link
|
88
|
-
for link
|
89
|
-
|
91
|
+
for link in html_resource.get_valid_css_links(
|
92
|
+
default_html_resource._css_links_manager
|
90
93
|
):
|
91
94
|
if isinstance(link, Path):
|
92
95
|
model.css_links.append(link)
|
93
96
|
|
94
97
|
# js file link to web static link
|
95
|
-
for info in
|
96
|
-
|
98
|
+
for info in html_resource.get_valid_js_links(
|
99
|
+
default_html_resource._js_links_manager
|
97
100
|
):
|
98
101
|
if isinstance(info.link, Path):
|
99
102
|
model.js_links.append(JsLink(info.link))
|
@@ -114,3 +117,7 @@ def get_template_model():
|
|
114
117
|
def to_html_str():
|
115
118
|
model = get_template_model()
|
116
119
|
return render_zero_html(model)
|
120
|
+
|
121
|
+
|
122
|
+
def _empty_html_resource():
|
123
|
+
return HtmlResource()
|
instaui/zero/scope.py
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
from pathlib import Path
|
2
|
-
from typing import Union
|
2
|
+
from typing import Dict, Optional, Union
|
3
3
|
from instaui.runtime import new_app_slot, reset_app_slot
|
4
4
|
from contextlib import contextmanager
|
5
5
|
from .func import to_html, to_html_str, get_template_model
|
@@ -7,8 +7,8 @@ from instaui.template.zero_template import ZeroTemplateModel
|
|
7
7
|
|
8
8
|
|
9
9
|
@contextmanager
|
10
|
-
def scope():
|
11
|
-
token = new_app_slot("zero")
|
10
|
+
def scope(app_meta: Optional[Dict] = None):
|
11
|
+
token = new_app_slot("zero", app_meta)
|
12
12
|
yield Wrapper()
|
13
13
|
reset_app_slot(token)
|
14
14
|
|
@@ -25,10 +25,10 @@ class Wrapper:
|
|
25
25
|
file = self._get_caller_path(file)
|
26
26
|
|
27
27
|
# Custom component dependencies must be recorded only during actual execution
|
28
|
-
to_html_str()
|
28
|
+
result_html_str = to_html_str()
|
29
29
|
model = get_template_model()
|
30
|
-
with scope() as s:
|
31
|
-
_create_debug_report(model)
|
30
|
+
with scope(app_meta={"merge_global_resources": False}) as s:
|
31
|
+
_create_debug_report(model, result_html_str)
|
32
32
|
s.to_html(file.resolve().absolute())
|
33
33
|
|
34
34
|
@staticmethod
|
@@ -44,8 +44,8 @@ class Wrapper:
|
|
44
44
|
return file
|
45
45
|
|
46
46
|
|
47
|
-
def _create_debug_report(model: ZeroTemplateModel):
|
48
|
-
from instaui import ui, html
|
47
|
+
def _create_debug_report(model: ZeroTemplateModel, result_html_str: str):
|
48
|
+
from instaui import ui, html, arco
|
49
49
|
|
50
50
|
no_exists_path_class = "ex-no-exists-path"
|
51
51
|
|
@@ -53,49 +53,50 @@ def _create_debug_report(model: ZeroTemplateModel):
|
|
53
53
|
return "" if path.exists() else no_exists_path_class
|
54
54
|
|
55
55
|
ui.use_tailwind()
|
56
|
+
|
56
57
|
ui.add_style(rf".{no_exists_path_class} {{background-color: red;color: white;}}")
|
57
58
|
|
59
|
+
html_size = len(result_html_str.encode("utf-8")) / 1024 / 1024
|
60
|
+
|
61
|
+
box_style = "border-2 border-gray-200 p-4 place-center gap-x-2"
|
62
|
+
|
58
63
|
with ui.column().classes("gap-2"):
|
64
|
+
# base info
|
65
|
+
with ui.grid(columns="auto 1fr").classes(box_style):
|
66
|
+
html.span("file size:")
|
67
|
+
html.span(f"{html_size:.2f} MB")
|
68
|
+
|
59
69
|
# import maps
|
60
70
|
html.paragraph("import maps")
|
61
|
-
with ui.grid(columns="auto 1fr").classes(
|
62
|
-
"gap-4 border-2 border-gray-200 p-4 place-center"
|
63
|
-
):
|
64
|
-
html.span("name")
|
65
|
-
html.span("path")
|
66
71
|
|
67
|
-
|
68
|
-
|
72
|
+
rows = [
|
73
|
+
["vue", str(model.vue_js_code)],
|
74
|
+
["instaui", str(model.instaui_js_code)],
|
75
|
+
]
|
69
76
|
|
70
|
-
|
71
|
-
|
77
|
+
for name, url in model.extra_import_maps.items():
|
78
|
+
if isinstance(url, Path) and url.is_file():
|
79
|
+
rows.append([name, str(url)])
|
72
80
|
|
73
|
-
|
74
|
-
if isinstance(url, Path) and url.is_file():
|
75
|
-
html.span(name)
|
76
|
-
html.span(str(url.resolve().absolute())).classes(
|
77
|
-
_path_exists_class(url)
|
78
|
-
)
|
81
|
+
arco.table(columns=["name", "path"], data=rows)
|
79
82
|
|
80
83
|
# css links
|
81
84
|
html.paragraph("css links")
|
82
|
-
with ui.column().classes(
|
85
|
+
with ui.column().classes(box_style):
|
83
86
|
for link in model.css_links:
|
84
87
|
if isinstance(link, Path) and link.is_file():
|
85
88
|
html.span(str(link)).classes(_path_exists_class(link))
|
86
89
|
|
87
90
|
# js links
|
88
91
|
html.paragraph("js links")
|
89
|
-
with ui.column().classes(
|
92
|
+
with ui.column().classes(box_style):
|
90
93
|
for info in model.js_links:
|
91
94
|
if isinstance(info.link, Path) and info.link.is_file():
|
92
95
|
html.span(str(info.link)).classes(_path_exists_class(info.link))
|
93
96
|
|
94
97
|
# custom components
|
95
98
|
html.paragraph("custom components")
|
96
|
-
with ui.grid(columns="auto 1fr").classes(
|
97
|
-
"gap-4 border-2 border-gray-200 p-4 place-center"
|
98
|
-
):
|
99
|
+
with ui.grid(columns="auto 1fr").classes(box_style):
|
99
100
|
html.span("name")
|
100
101
|
html.span("js file path")
|
101
102
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: instaui
|
3
|
-
Version: 0.1.
|
3
|
+
Version: 0.1.6
|
4
4
|
Summary: insta-ui is a Python-based UI library for rapidly building user interfaces.
|
5
5
|
License: MIT
|
6
6
|
Author: CrystalWindSnake
|
@@ -13,14 +13,18 @@ Classifier: Programming Language :: Python :: 3.9
|
|
13
13
|
Classifier: Programming Language :: Python :: 3.10
|
14
14
|
Classifier: Programming Language :: Python :: 3.11
|
15
15
|
Classifier: Programming Language :: Python :: 3.12
|
16
|
+
Provides-Extra: all
|
16
17
|
Provides-Extra: web
|
17
18
|
Provides-Extra: webview
|
18
|
-
Requires-Dist: fastapi ; extra == "
|
19
|
+
Requires-Dist: fastapi[standard] ; extra == "all"
|
20
|
+
Requires-Dist: fastapi[standard] ; extra == "web"
|
19
21
|
Requires-Dist: jinja2 (>=3.1.4,<4.0.0)
|
20
22
|
Requires-Dist: orjson (>=3.10.15,<4.0.0)
|
21
23
|
Requires-Dist: pydantic (>=2.10.6,<3.0.0)
|
24
|
+
Requires-Dist: pywebview ; extra == "all"
|
22
25
|
Requires-Dist: pywebview ; extra == "webview"
|
23
26
|
Requires-Dist: typing-extensions (>=4.12.2,<5.0.0)
|
27
|
+
Requires-Dist: uvicorn ; extra == "all"
|
24
28
|
Requires-Dist: uvicorn ; extra == "web"
|
25
29
|
Description-Content-Type: text/markdown
|
26
30
|
|