Mercurial > libervia-web
view libervia/server/tasks/implicit/task_brython.py @ 1256:08cd652dea14
server, pages, tasks (brython): common_scripts:
- scripts common to all pages can now be put in root `_browser` dir
- `scripts` list is not set in `dyn_data`'s `template` anymore, but directly in a root
`scripts` key (because it's not data which are sent verbatim to the template renderer)
- if an `__init__.py` script is found in root `_browser` dir, brython task will add it to
template scripts.
author | Goffi <goffi@goffi.org> |
---|---|
date | Sun, 03 May 2020 18:15:22 +0200 |
parents | 6d49fae517ba |
children | 3fc3f2cde6a1 |
line wrap: on
line source
#!/ur/bin/env python3 import shutil import json from pathlib import Path from ast import literal_eval from sat.core.i18n import _ from sat.core.log import getLogger from sat.core import exceptions from libervia.server.constants import Const as C from libervia.server.tasks import task log = getLogger(__name__) class Task(task.Task): def prepare(self): if "brython" not in self.resource.browser_modules: raise exceptions.CancelError(f"No brython module found") brython_js = self.build_path / "brython.js" if not brython_js.is_file(): installed_ver = None else: with brython_js.open() as f: for line in f: if line.startswith('// implementation ['): installed_ver = literal_eval(line[18:])[:3] log.debug( f"brython v{'.'.join(str(v) for v in installed_ver)} already " f"installed") break else: log.warning( f"brython file at {brython_js} doesn't has implementation " f"version" ) installed_ver = None try: import brython except ModuleNotFoundError as e: log.error('"brython" module is missing, can\'t use browser code for Brython') raise e ver = [int(v) for v in brython.implementation.split('.')[:3]] if ver != installed_ver: log.info(_("Installing Brython v{version}").format( version='.'.join(str(v) for v in ver))) data_path = Path(brython.__file__).parent / 'data' # shutil has blocking method, but the task is run before we start # the web server, so it's not a big deal shutil.copyfile(data_path / "brython.js", brython_js) else: log.debug("Brython is already installed") self.WATCH_DIRS = [] for dyn_data in self.resource.browser_modules["brython"]: url_hash = dyn_data['url_hash'] import_url = f"/{C.BUILD_DIR}/{C.BUILD_DIR_DYN}/{url_hash}" on_load_opts = { "debug": 1, "cache": True, "pythonpath": [f"/{C.BUILD_DIR}", import_url], } dyn_data.setdefault('scripts', set()).extend([ {"src": f"/{C.BUILD_DIR}/brython.js"}, ]) dyn_data.setdefault('template', {})['body_onload'] = ( f"brython({json.dumps(on_load_opts)})") self.WATCH_DIRS.append(dyn_data['path'].resolve()) def copyFiles(self, files_paths, dest): for p in files_paths: log.debug(f"copying {p}") if p.is_dir(): shutil.copytree(p, dest) else: shutil.copy(p, dest) def start(self): dyn_path = self.build_path / C.BUILD_DIR_DYN for dyn_data in self.resource.browser_modules["brython"]: url_hash = dyn_data['url_hash'] if url_hash is None: # root modules url_prefix = dyn_data.get('url_prefix') if url_prefix is None: dest = self.build_path init_dest_url = f"/{C.BUILD_DIR}/__init__.py" else: dest = self.build_path / url_prefix dest.mkdir(exist_ok = True) init_dest_url = f"/{C.BUILD_DIR}/{url_prefix}/__init__.py" self.copyFiles(dyn_data['path'].glob('*py'), dest) init_file = dyn_data['path'] / '__init__.py' if init_file.is_file(): common_scripts = self.resource.dyn_data_common['scripts'] script = { 'type': 'text/python', 'src': init_dest_url } if script not in common_scripts: common_scripts.append(script) else: page_dyn_path = dyn_path / url_hash if page_dyn_path.exists(): log.debug("cleaning existing path") shutil.rmtree(page_dyn_path) page_dyn_path.mkdir(parents=True, exist_ok=True) log.debug("copying browser python files") self.copyFiles(dyn_data['path'].iterdir(), page_dyn_path) script = { 'type': 'text/python', 'src': f"/{C.BUILD_DIR}/{C.BUILD_DIR_DYN}/{url_hash}/__init__.py" } scripts = dyn_data['scripts'] if script not in scripts: scripts.append(script)