mirror of
https://github.com/LC044/WeChatMsg
synced 2024-11-15 14:31:18 +08:00
122 lines
4.0 KiB
Python
122 lines
4.0 KiB
Python
|
import os
|
||
|
|
||
|
try:
|
||
|
from collections.abc import Iterable
|
||
|
except ImportError:
|
||
|
from collections import Iterable
|
||
|
|
||
|
from jinja2 import Environment
|
||
|
|
||
|
from ..commons import utils
|
||
|
from ..datasets import EXTRA, FILENAMES
|
||
|
from ..globals import CurrentConfig, NotebookType
|
||
|
from ..types import Any, Optional
|
||
|
from .display import HTML, Javascript
|
||
|
|
||
|
|
||
|
def write_utf8_html_file(file_name: str, html_content: str):
|
||
|
with open(file_name, "w+", encoding="utf-8") as html_file:
|
||
|
html_file.write(html_content)
|
||
|
|
||
|
|
||
|
class RenderEngine:
|
||
|
def __init__(self, env: Optional[Environment] = None):
|
||
|
self.env = env or CurrentConfig.GLOBAL_ENV
|
||
|
|
||
|
@staticmethod
|
||
|
def generate_js_link(chart: Any) -> Any:
|
||
|
if not chart.js_host:
|
||
|
chart.js_host = CurrentConfig.ONLINE_HOST
|
||
|
links = []
|
||
|
for dep in chart.js_dependencies.items:
|
||
|
# TODO: if?
|
||
|
if dep.startswith("https://api.map.baidu.com"):
|
||
|
links.append(dep)
|
||
|
if dep in FILENAMES:
|
||
|
f, ext = FILENAMES[dep]
|
||
|
links.append("{}{}.{}".format(chart.js_host, f, ext))
|
||
|
else:
|
||
|
for url, files in EXTRA.items():
|
||
|
if dep in files:
|
||
|
f, ext = files[dep]
|
||
|
links.append("{}{}.{}".format(url, f, ext))
|
||
|
break
|
||
|
chart.dependencies = links
|
||
|
return chart
|
||
|
|
||
|
def render_chart_to_file(self, template_name: str, chart: Any, path: str, **kwargs):
|
||
|
"""
|
||
|
Render a chart or page to local html files.
|
||
|
|
||
|
:param chart: A Chart or Page object
|
||
|
:param path: The destination file which the html code write to
|
||
|
:param template_name: The name of template file.
|
||
|
"""
|
||
|
tpl = self.env.get_template(template_name)
|
||
|
html = utils.replace_placeholder(
|
||
|
tpl.render(chart=self.generate_js_link(chart), **kwargs)
|
||
|
)
|
||
|
write_utf8_html_file(path, html)
|
||
|
|
||
|
def render_chart_to_template(self, template_name: str, chart: Any, **kwargs) -> str:
|
||
|
tpl = self.env.get_template(template_name)
|
||
|
return utils.replace_placeholder(
|
||
|
tpl.render(chart=self.generate_js_link(chart), **kwargs)
|
||
|
)
|
||
|
|
||
|
def render_chart_to_notebook(self, template_name: str, **kwargs) -> str:
|
||
|
tpl = self.env.get_template(template_name)
|
||
|
return utils.replace_placeholder(tpl.render(**kwargs))
|
||
|
|
||
|
|
||
|
def render(
|
||
|
chart, path: str, template_name: str, env: Optional[Environment], **kwargs
|
||
|
) -> str:
|
||
|
RenderEngine(env).render_chart_to_file(
|
||
|
template_name=template_name, chart=chart, path=path, **kwargs
|
||
|
)
|
||
|
return os.path.abspath(path)
|
||
|
|
||
|
|
||
|
def render_embed(
|
||
|
chart, template_name: str, env: Optional[Environment], **kwargs
|
||
|
) -> str:
|
||
|
return RenderEngine(env).render_chart_to_template(
|
||
|
template_name=template_name, chart=chart, **kwargs
|
||
|
)
|
||
|
|
||
|
|
||
|
def render_notebook(self, notebook_template, lab_template):
|
||
|
instance = self if isinstance(self, Iterable) else (self,)
|
||
|
if CurrentConfig.NOTEBOOK_TYPE == NotebookType.JUPYTER_NOTEBOOK:
|
||
|
require_config = utils.produce_require_dict(self.js_dependencies, self.js_host)
|
||
|
return HTML(
|
||
|
RenderEngine().render_chart_to_notebook(
|
||
|
template_name=notebook_template,
|
||
|
charts=instance,
|
||
|
config_items=require_config["config_items"],
|
||
|
libraries=require_config["libraries"],
|
||
|
)
|
||
|
)
|
||
|
|
||
|
if CurrentConfig.NOTEBOOK_TYPE == NotebookType.JUPYTER_LAB:
|
||
|
return HTML(
|
||
|
RenderEngine().render_chart_to_notebook(
|
||
|
template_name=lab_template, charts=instance
|
||
|
)
|
||
|
)
|
||
|
|
||
|
if CurrentConfig.NOTEBOOK_TYPE == NotebookType.NTERACT:
|
||
|
return HTML(self.render_embed())
|
||
|
|
||
|
if CurrentConfig.NOTEBOOK_TYPE == NotebookType.ZEPPELIN:
|
||
|
print("%html " + self.render_embed())
|
||
|
|
||
|
|
||
|
def load_javascript(chart):
|
||
|
scripts = []
|
||
|
for dep in chart.js_dependencies.items:
|
||
|
f, ext = FILENAMES[dep]
|
||
|
scripts.append("{}{}.{}".format(CurrentConfig.ONLINE_HOST, f, ext))
|
||
|
return Javascript(lib=scripts)
|