Mercurial > libervia-web
comparison 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 |
comparison
equal
deleted
inserted
replaced
1246:aaf28d45ae67 | 1247:a6c7f07f1e4d |
---|---|
1 #!/ur/bin/env python3 | |
2 | |
3 import shutil | |
4 import json | |
5 from pathlib import Path | |
6 from ast import literal_eval | |
7 from sat.core.i18n import _ | |
8 from sat.core.log import getLogger | |
9 from sat.core import exceptions | |
10 from sat.tools.common.template import safe | |
11 from libervia.server.constants import Const as C | |
12 from libervia.server.tasks import task | |
13 | |
14 | |
15 log = getLogger(__name__) | |
16 | |
17 | |
18 class Task(task.Task): | |
19 DOC_DIRS_DEFAULT = ('doc', 'docs') | |
20 | |
21 def prepare(self): | |
22 if "brython" not in self.resource.browser_modules: | |
23 raise exceptions.CancelError(f"No brython module found") | |
24 | |
25 brython_js = self.build_path / "brython.js" | |
26 if not brython_js.is_file(): | |
27 installed_ver = None | |
28 else: | |
29 with brython_js.open() as f: | |
30 for line in f: | |
31 if line.startswith('// implementation ['): | |
32 installed_ver = literal_eval(line[18:])[:3] | |
33 log.debug( | |
34 f"brython v{'.'.join(str(v) for v in installed_ver)} already " | |
35 f"installed") | |
36 break | |
37 else: | |
38 log.warning( | |
39 f"brython file at {brython_js} doesn't has implementation " | |
40 f"version" | |
41 ) | |
42 installed_ver = None | |
43 | |
44 import brython | |
45 ver = [int(v) for v in brython.implementation.split('.')[:3]] | |
46 if ver != installed_ver: | |
47 log.info(_("Installing Brython v{version}").format( | |
48 version='.'.join(str(v) for v in ver))) | |
49 data_path = Path(brython.__file__).parent / 'data' | |
50 # shutil has blocking method, but the task is run before we start | |
51 # the web server, so it's not a big deal | |
52 shutil.copyfile(data_path / "brython.js", brython_js) | |
53 else: | |
54 log.debug("Brython is already installed") | |
55 | |
56 self.WATCH_DIRS = [] | |
57 | |
58 for dyn_data in self.resource.browser_modules["brython"]: | |
59 url_hash = dyn_data['url_hash'] | |
60 import_url = f"/{C.BUILD_DIR}/{C.BUILD_DIR_DYN}/{url_hash}" | |
61 on_load_opts = { | |
62 "debug": 1, | |
63 "pythonpath": [import_url], | |
64 } | |
65 dyn_data['template'] = { | |
66 "scripts": [{"src": f"/{C.BUILD_DIR}/brython.js"}], | |
67 "body_onload": f"brython({json.dumps(on_load_opts)})", | |
68 } | |
69 self.WATCH_DIRS.append(dyn_data['path'].resolve()) | |
70 | |
71 def start(self): | |
72 dyn_path = self.build_path / C.BUILD_DIR_DYN | |
73 for dyn_data in self.resource.browser_modules["brython"]: | |
74 url_hash = dyn_data['url_hash'] | |
75 page_dyn_path = dyn_path / url_hash | |
76 if page_dyn_path.exists(): | |
77 log.debug("cleaning existing path") | |
78 shutil.rmtree(page_dyn_path) | |
79 | |
80 page_dyn_path.mkdir(parents=True, exist_ok=True) | |
81 log.debug("copying browser python files") | |
82 for p in dyn_data['path'].iterdir(): | |
83 log.debug(f"copying {p}") | |
84 if p.is_dir(): | |
85 shutil.copytree(p, page_dyn_path) | |
86 else: | |
87 shutil.copy(p, page_dyn_path) | |
88 | |
89 script = { | |
90 'type': 'text/python', | |
91 'src': f"/{C.BUILD_DIR}/{C.BUILD_DIR_DYN}/{url_hash}/__init__.py" | |
92 } | |
93 scripts = dyn_data['template']['scripts'] | |
94 if script not in scripts: | |
95 scripts.append(script) |