Mercurial > libervia-web
diff libervia/server/tasks/implicit/task_brython.py @ 1247:a6c7f07f1e4d
tasks: implicit tasks + Brython task:
- implicit tasks are tasks launched for every site.
- a first one is made for Brython: it will install Brython and copy suitable files and set
template data if Brython code is written in page `_browser` subdirectory.
author | Goffi <goffi@goffi.org> |
---|---|
date | Sun, 26 Apr 2020 22:07:18 +0200 |
parents | |
children | 821b6ce57f99 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libervia/server/tasks/implicit/task_brython.py Sun Apr 26 22:07:18 2020 +0200 @@ -0,0 +1,95 @@ +#!/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 sat.tools.common.template import safe +from libervia.server.constants import Const as C +from libervia.server.tasks import task + + +log = getLogger(__name__) + + +class Task(task.Task): + DOC_DIRS_DEFAULT = ('doc', 'docs') + + 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 + + import brython + 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, + "pythonpath": [import_url], + } + dyn_data['template'] = { + "scripts": [{"src": f"/{C.BUILD_DIR}/brython.js"}], + "body_onload": f"brython({json.dumps(on_load_opts)})", + } + self.WATCH_DIRS.append(dyn_data['path'].resolve()) + + 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'] + 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") + for p in dyn_data['path'].iterdir(): + log.debug(f"copying {p}") + if p.is_dir(): + shutil.copytree(p, page_dyn_path) + else: + shutil.copy(p, page_dyn_path) + + script = { + 'type': 'text/python', + 'src': f"/{C.BUILD_DIR}/{C.BUILD_DIR_DYN}/{url_hash}/__init__.py" + } + scripts = dyn_data['template']['scripts'] + if script not in scripts: + scripts.append(script)