Mercurial > libervia-web
annotate libervia/server/tasks/implicit/task_brython.py @ 1250:821b6ce57f99
server (tasks/brython): log an error if brython is missing and needed
author | Goffi <goffi@goffi.org> |
---|---|
date | Mon, 27 Apr 2020 10:55:23 +0200 |
parents | a6c7f07f1e4d |
children | 6d49fae517ba |
rev | line source |
---|---|
1247 | 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 | |
1250
821b6ce57f99
server (tasks/brython): log an error if brython is missing and needed
Goffi <goffi@goffi.org>
parents:
1247
diff
changeset
|
44 try: |
821b6ce57f99
server (tasks/brython): log an error if brython is missing and needed
Goffi <goffi@goffi.org>
parents:
1247
diff
changeset
|
45 import brython |
821b6ce57f99
server (tasks/brython): log an error if brython is missing and needed
Goffi <goffi@goffi.org>
parents:
1247
diff
changeset
|
46 except ModuleNotFoundError as e: |
821b6ce57f99
server (tasks/brython): log an error if brython is missing and needed
Goffi <goffi@goffi.org>
parents:
1247
diff
changeset
|
47 log.error('"brython" module is missing, can\'t use browser code for Brython') |
821b6ce57f99
server (tasks/brython): log an error if brython is missing and needed
Goffi <goffi@goffi.org>
parents:
1247
diff
changeset
|
48 raise e |
1247 | 49 ver = [int(v) for v in brython.implementation.split('.')[:3]] |
50 if ver != installed_ver: | |
51 log.info(_("Installing Brython v{version}").format( | |
52 version='.'.join(str(v) for v in ver))) | |
53 data_path = Path(brython.__file__).parent / 'data' | |
54 # shutil has blocking method, but the task is run before we start | |
55 # the web server, so it's not a big deal | |
56 shutil.copyfile(data_path / "brython.js", brython_js) | |
57 else: | |
58 log.debug("Brython is already installed") | |
59 | |
60 self.WATCH_DIRS = [] | |
61 | |
62 for dyn_data in self.resource.browser_modules["brython"]: | |
63 url_hash = dyn_data['url_hash'] | |
64 import_url = f"/{C.BUILD_DIR}/{C.BUILD_DIR_DYN}/{url_hash}" | |
65 on_load_opts = { | |
66 "debug": 1, | |
67 "pythonpath": [import_url], | |
68 } | |
69 dyn_data['template'] = { | |
70 "scripts": [{"src": f"/{C.BUILD_DIR}/brython.js"}], | |
71 "body_onload": f"brython({json.dumps(on_load_opts)})", | |
72 } | |
73 self.WATCH_DIRS.append(dyn_data['path'].resolve()) | |
74 | |
75 def start(self): | |
76 dyn_path = self.build_path / C.BUILD_DIR_DYN | |
77 for dyn_data in self.resource.browser_modules["brython"]: | |
78 url_hash = dyn_data['url_hash'] | |
79 page_dyn_path = dyn_path / url_hash | |
80 if page_dyn_path.exists(): | |
81 log.debug("cleaning existing path") | |
82 shutil.rmtree(page_dyn_path) | |
83 | |
84 page_dyn_path.mkdir(parents=True, exist_ok=True) | |
85 log.debug("copying browser python files") | |
86 for p in dyn_data['path'].iterdir(): | |
87 log.debug(f"copying {p}") | |
88 if p.is_dir(): | |
89 shutil.copytree(p, page_dyn_path) | |
90 else: | |
91 shutil.copy(p, page_dyn_path) | |
92 | |
93 script = { | |
94 'type': 'text/python', | |
95 'src': f"/{C.BUILD_DIR}/{C.BUILD_DIR_DYN}/{url_hash}/__init__.py" | |
96 } | |
97 scripts = dyn_data['template']['scripts'] | |
98 if script not in scripts: | |
99 scripts.append(script) |