Mercurial > libervia-web
annotate libervia/server/tasks/implicit/task_brython.py @ 1503:2796e73ed50c
tasks (brython): fix brython scripts loading.
author | Goffi <goffi@goffi.org> |
---|---|
date | Wed, 01 Mar 2023 17:55:25 +0100 |
parents | b61509c47cac |
children | 106bae41f5c8 |
rev | line source |
---|---|
1247 | 1 #!/ur/bin/env python3 |
2 | |
1503
2796e73ed50c
tasks (brython): fix brython scripts loading.
Goffi <goffi@goffi.org>
parents:
1384
diff
changeset
|
3 from ast import literal_eval |
1247 | 4 import json |
5 from pathlib import Path | |
1503
2796e73ed50c
tasks (brython): fix brython scripts loading.
Goffi <goffi@goffi.org>
parents:
1384
diff
changeset
|
6 import shutil |
2796e73ed50c
tasks (brython): fix brython scripts loading.
Goffi <goffi@goffi.org>
parents:
1384
diff
changeset
|
7 from typing import Any, Dict |
2796e73ed50c
tasks (brython): fix brython scripts loading.
Goffi <goffi@goffi.org>
parents:
1384
diff
changeset
|
8 |
2796e73ed50c
tasks (brython): fix brython scripts loading.
Goffi <goffi@goffi.org>
parents:
1384
diff
changeset
|
9 from sat.core import exceptions |
1247 | 10 from sat.core.i18n import _ |
11 from sat.core.log import getLogger | |
1282
0e4e413eb8db
server: user new OrderedSet to handle scripts:
Goffi <goffi@goffi.org>
parents:
1279
diff
changeset
|
12 from sat.tools.common import utils |
1503
2796e73ed50c
tasks (brython): fix brython scripts loading.
Goffi <goffi@goffi.org>
parents:
1384
diff
changeset
|
13 |
2796e73ed50c
tasks (brython): fix brython scripts loading.
Goffi <goffi@goffi.org>
parents:
1384
diff
changeset
|
14 from libervia.server.classes import Script |
1247 | 15 from libervia.server.constants import Const as C |
16 from libervia.server.tasks import task | |
17 | |
18 | |
19 log = getLogger(__name__) | |
20 | |
21 | |
22 class Task(task.Task): | |
23 | |
24 def prepare(self): | |
25 if "brython" not in self.resource.browser_modules: | |
1326
089742e065e3
pages (files/list, photos/album): updated thumbnails size limits
Goffi <goffi@goffi.org>
parents:
1282
diff
changeset
|
26 raise exceptions.CancelError("No brython module found") |
1247 | 27 |
28 brython_js = self.build_path / "brython.js" | |
29 if not brython_js.is_file(): | |
30 installed_ver = None | |
31 else: | |
32 with brython_js.open() as f: | |
33 for line in f: | |
34 if line.startswith('// implementation ['): | |
35 installed_ver = literal_eval(line[18:])[:3] | |
36 log.debug( | |
37 f"brython v{'.'.join(str(v) for v in installed_ver)} already " | |
38 f"installed") | |
39 break | |
40 else: | |
41 log.warning( | |
42 f"brython file at {brython_js} doesn't has implementation " | |
43 f"version" | |
44 ) | |
45 installed_ver = None | |
46 | |
1250
821b6ce57f99
server (tasks/brython): log an error if brython is missing and needed
Goffi <goffi@goffi.org>
parents:
1247
diff
changeset
|
47 try: |
821b6ce57f99
server (tasks/brython): log an error if brython is missing and needed
Goffi <goffi@goffi.org>
parents:
1247
diff
changeset
|
48 import brython |
1503
2796e73ed50c
tasks (brython): fix brython scripts loading.
Goffi <goffi@goffi.org>
parents:
1384
diff
changeset
|
49 from brython import version as brython_version |
1250
821b6ce57f99
server (tasks/brython): log an error if brython is missing and needed
Goffi <goffi@goffi.org>
parents:
1247
diff
changeset
|
50 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
|
51 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
|
52 raise e |
1503
2796e73ed50c
tasks (brython): fix brython scripts loading.
Goffi <goffi@goffi.org>
parents:
1384
diff
changeset
|
53 ver = [int(v) for v in brython_version.implementation.split('.')[:3]] |
1247 | 54 if ver != installed_ver: |
55 log.info(_("Installing Brython v{version}").format( | |
56 version='.'.join(str(v) for v in ver))) | |
57 data_path = Path(brython.__file__).parent / 'data' | |
58 # shutil has blocking method, but the task is run before we start | |
59 # the web server, so it's not a big deal | |
60 shutil.copyfile(data_path / "brython.js", brython_js) | |
1279
2d1ceb026d0e
tasks (brython): copy and load `brython_stdlib.js`
Goffi <goffi@goffi.org>
parents:
1268
diff
changeset
|
61 shutil.copy(data_path / "brython_stdlib.js", self.build_path) |
1247 | 62 else: |
63 log.debug("Brython is already installed") | |
64 | |
65 self.WATCH_DIRS = [] | |
1503
2796e73ed50c
tasks (brython): fix brython scripts loading.
Goffi <goffi@goffi.org>
parents:
1384
diff
changeset
|
66 self.set_common_scripts() |
1247 | 67 |
1503
2796e73ed50c
tasks (brython): fix brython scripts loading.
Goffi <goffi@goffi.org>
parents:
1384
diff
changeset
|
68 def set_common_scripts(self): |
1247 | 69 for dyn_data in self.resource.browser_modules["brython"]: |
70 url_hash = dyn_data['url_hash'] | |
71 import_url = f"/{C.BUILD_DIR}/{C.BUILD_DIR_DYN}/{url_hash}" | |
1282
0e4e413eb8db
server: user new OrderedSet to handle scripts:
Goffi <goffi@goffi.org>
parents:
1279
diff
changeset
|
72 dyn_data.setdefault('scripts', utils.OrderedSet()).update([ |
1268
e628724530ec
pages, tasks (brython): use set for scripts + common template data:
Goffi <goffi@goffi.org>
parents:
1262
diff
changeset
|
73 Script(src=f"/{C.BUILD_DIR}/brython.js"), |
1279
2d1ceb026d0e
tasks (brython): copy and load `brython_stdlib.js`
Goffi <goffi@goffi.org>
parents:
1268
diff
changeset
|
74 Script(src=f"/{C.BUILD_DIR}/brython_stdlib.js"), |
1282
0e4e413eb8db
server: user new OrderedSet to handle scripts:
Goffi <goffi@goffi.org>
parents:
1279
diff
changeset
|
75 ]) |
1503
2796e73ed50c
tasks (brython): fix brython scripts loading.
Goffi <goffi@goffi.org>
parents:
1384
diff
changeset
|
76 dyn_data.setdefault('template', {})['body_onload'] = self.get_body_onload( |
1268
e628724530ec
pages, tasks (brython): use set for scripts + common template data:
Goffi <goffi@goffi.org>
parents:
1262
diff
changeset
|
77 extra_path=[import_url]) |
1247 | 78 self.WATCH_DIRS.append(dyn_data['path'].resolve()) |
79 | |
1503
2796e73ed50c
tasks (brython): fix brython scripts loading.
Goffi <goffi@goffi.org>
parents:
1384
diff
changeset
|
80 def get_body_onload(self, debug=True, cache=True, extra_path=None): |
2796e73ed50c
tasks (brython): fix brython scripts loading.
Goffi <goffi@goffi.org>
parents:
1384
diff
changeset
|
81 on_load_opts: Dict[str, Any] = {"pythonpath": [f"/{C.BUILD_DIR}"]} |
2796e73ed50c
tasks (brython): fix brython scripts loading.
Goffi <goffi@goffi.org>
parents:
1384
diff
changeset
|
82 if debug: |
2796e73ed50c
tasks (brython): fix brython scripts loading.
Goffi <goffi@goffi.org>
parents:
1384
diff
changeset
|
83 on_load_opts["debug"] = 1 |
2796e73ed50c
tasks (brython): fix brython scripts loading.
Goffi <goffi@goffi.org>
parents:
1384
diff
changeset
|
84 if cache: |
2796e73ed50c
tasks (brython): fix brython scripts loading.
Goffi <goffi@goffi.org>
parents:
1384
diff
changeset
|
85 on_load_opts["cache"] = True |
2796e73ed50c
tasks (brython): fix brython scripts loading.
Goffi <goffi@goffi.org>
parents:
1384
diff
changeset
|
86 if extra_path is not None: |
2796e73ed50c
tasks (brython): fix brython scripts loading.
Goffi <goffi@goffi.org>
parents:
1384
diff
changeset
|
87 on_load_opts["pythonpath"].extend(extra_path) |
1268
e628724530ec
pages, tasks (brython): use set for scripts + common template data:
Goffi <goffi@goffi.org>
parents:
1262
diff
changeset
|
88 |
1503
2796e73ed50c
tasks (brython): fix brython scripts loading.
Goffi <goffi@goffi.org>
parents:
1384
diff
changeset
|
89 return f"brython({json.dumps(on_load_opts)})" |
1268
e628724530ec
pages, tasks (brython): use set for scripts + common template data:
Goffi <goffi@goffi.org>
parents:
1262
diff
changeset
|
90 |
1503
2796e73ed50c
tasks (brython): fix brython scripts loading.
Goffi <goffi@goffi.org>
parents:
1384
diff
changeset
|
91 def copy_files(self, files_paths, dest): |
1253
6d49fae517ba
pages: browser metadata + root `_browser`:
Goffi <goffi@goffi.org>
parents:
1250
diff
changeset
|
92 for p in files_paths: |
6d49fae517ba
pages: browser metadata + root `_browser`:
Goffi <goffi@goffi.org>
parents:
1250
diff
changeset
|
93 log.debug(f"copying {p}") |
6d49fae517ba
pages: browser metadata + root `_browser`:
Goffi <goffi@goffi.org>
parents:
1250
diff
changeset
|
94 if p.is_dir(): |
1335
f2ce8072d89d
tasks (brython): don't copy `__pycache__` to build_dir + fixed recursive copy
Goffi <goffi@goffi.org>
parents:
1326
diff
changeset
|
95 if p.name == '__pycache__': |
f2ce8072d89d
tasks (brython): don't copy `__pycache__` to build_dir + fixed recursive copy
Goffi <goffi@goffi.org>
parents:
1326
diff
changeset
|
96 continue |
f2ce8072d89d
tasks (brython): don't copy `__pycache__` to build_dir + fixed recursive copy
Goffi <goffi@goffi.org>
parents:
1326
diff
changeset
|
97 shutil.copytree(p, dest / p.name) |
1253
6d49fae517ba
pages: browser metadata + root `_browser`:
Goffi <goffi@goffi.org>
parents:
1250
diff
changeset
|
98 else: |
6d49fae517ba
pages: browser metadata + root `_browser`:
Goffi <goffi@goffi.org>
parents:
1250
diff
changeset
|
99 shutil.copy(p, dest) |
6d49fae517ba
pages: browser metadata + root `_browser`:
Goffi <goffi@goffi.org>
parents:
1250
diff
changeset
|
100 |
1384
b61509c47cac
tasks (brython): fixed Brython scripts during dev mode reload
Goffi <goffi@goffi.org>
parents:
1335
diff
changeset
|
101 async def onDirEvent(self, host, filepath, flags): |
1503
2796e73ed50c
tasks (brython): fix brython scripts loading.
Goffi <goffi@goffi.org>
parents:
1384
diff
changeset
|
102 self.set_common_scripts() |
1384
b61509c47cac
tasks (brython): fixed Brython scripts during dev mode reload
Goffi <goffi@goffi.org>
parents:
1335
diff
changeset
|
103 await self.manager.runTaskInstance(self) |
b61509c47cac
tasks (brython): fixed Brython scripts during dev mode reload
Goffi <goffi@goffi.org>
parents:
1335
diff
changeset
|
104 |
1247 | 105 def start(self): |
106 dyn_path = self.build_path / C.BUILD_DIR_DYN | |
107 for dyn_data in self.resource.browser_modules["brython"]: | |
108 url_hash = dyn_data['url_hash'] | |
1253
6d49fae517ba
pages: browser metadata + root `_browser`:
Goffi <goffi@goffi.org>
parents:
1250
diff
changeset
|
109 if url_hash is None: |
6d49fae517ba
pages: browser metadata + root `_browser`:
Goffi <goffi@goffi.org>
parents:
1250
diff
changeset
|
110 # root modules |
1256
08cd652dea14
server, pages, tasks (brython): common_scripts:
Goffi <goffi@goffi.org>
parents:
1253
diff
changeset
|
111 url_prefix = dyn_data.get('url_prefix') |
08cd652dea14
server, pages, tasks (brython): common_scripts:
Goffi <goffi@goffi.org>
parents:
1253
diff
changeset
|
112 if url_prefix is None: |
08cd652dea14
server, pages, tasks (brython): common_scripts:
Goffi <goffi@goffi.org>
parents:
1253
diff
changeset
|
113 dest = self.build_path |
08cd652dea14
server, pages, tasks (brython): common_scripts:
Goffi <goffi@goffi.org>
parents:
1253
diff
changeset
|
114 init_dest_url = f"/{C.BUILD_DIR}/__init__.py" |
08cd652dea14
server, pages, tasks (brython): common_scripts:
Goffi <goffi@goffi.org>
parents:
1253
diff
changeset
|
115 else: |
08cd652dea14
server, pages, tasks (brython): common_scripts:
Goffi <goffi@goffi.org>
parents:
1253
diff
changeset
|
116 dest = self.build_path / url_prefix |
08cd652dea14
server, pages, tasks (brython): common_scripts:
Goffi <goffi@goffi.org>
parents:
1253
diff
changeset
|
117 dest.mkdir(exist_ok = True) |
08cd652dea14
server, pages, tasks (brython): common_scripts:
Goffi <goffi@goffi.org>
parents:
1253
diff
changeset
|
118 init_dest_url = f"/{C.BUILD_DIR}/{url_prefix}/__init__.py" |
08cd652dea14
server, pages, tasks (brython): common_scripts:
Goffi <goffi@goffi.org>
parents:
1253
diff
changeset
|
119 |
1503
2796e73ed50c
tasks (brython): fix brython scripts loading.
Goffi <goffi@goffi.org>
parents:
1384
diff
changeset
|
120 self.copy_files(dyn_data['path'].glob('*py'), dest) |
1256
08cd652dea14
server, pages, tasks (brython): common_scripts:
Goffi <goffi@goffi.org>
parents:
1253
diff
changeset
|
121 |
08cd652dea14
server, pages, tasks (brython): common_scripts:
Goffi <goffi@goffi.org>
parents:
1253
diff
changeset
|
122 init_file = dyn_data['path'] / '__init__.py' |
08cd652dea14
server, pages, tasks (brython): common_scripts:
Goffi <goffi@goffi.org>
parents:
1253
diff
changeset
|
123 if init_file.is_file(): |
1282
0e4e413eb8db
server: user new OrderedSet to handle scripts:
Goffi <goffi@goffi.org>
parents:
1279
diff
changeset
|
124 self.resource.dyn_data_common['scripts'].update([ |
1268
e628724530ec
pages, tasks (brython): use set for scripts + common template data:
Goffi <goffi@goffi.org>
parents:
1262
diff
changeset
|
125 Script(src=f"/{C.BUILD_DIR}/brython.js"), |
1503
2796e73ed50c
tasks (brython): fix brython scripts loading.
Goffi <goffi@goffi.org>
parents:
1384
diff
changeset
|
126 Script(src=f"/{C.BUILD_DIR}/brython_stdlib.js"), |
1268
e628724530ec
pages, tasks (brython): use set for scripts + common template data:
Goffi <goffi@goffi.org>
parents:
1262
diff
changeset
|
127 Script(type='text/python', src=init_dest_url) |
1282
0e4e413eb8db
server: user new OrderedSet to handle scripts:
Goffi <goffi@goffi.org>
parents:
1279
diff
changeset
|
128 ]) |
1268
e628724530ec
pages, tasks (brython): use set for scripts + common template data:
Goffi <goffi@goffi.org>
parents:
1262
diff
changeset
|
129 self.resource.dyn_data_common.setdefault( |
1503
2796e73ed50c
tasks (brython): fix brython scripts loading.
Goffi <goffi@goffi.org>
parents:
1384
diff
changeset
|
130 "template", {})['body_onload'] = self.get_body_onload() |
1253
6d49fae517ba
pages: browser metadata + root `_browser`:
Goffi <goffi@goffi.org>
parents:
1250
diff
changeset
|
131 else: |
6d49fae517ba
pages: browser metadata + root `_browser`:
Goffi <goffi@goffi.org>
parents:
1250
diff
changeset
|
132 page_dyn_path = dyn_path / url_hash |
1335
f2ce8072d89d
tasks (brython): don't copy `__pycache__` to build_dir + fixed recursive copy
Goffi <goffi@goffi.org>
parents:
1326
diff
changeset
|
133 log.debug(f"using dynamic path at {page_dyn_path}") |
1253
6d49fae517ba
pages: browser metadata + root `_browser`:
Goffi <goffi@goffi.org>
parents:
1250
diff
changeset
|
134 if page_dyn_path.exists(): |
6d49fae517ba
pages: browser metadata + root `_browser`:
Goffi <goffi@goffi.org>
parents:
1250
diff
changeset
|
135 log.debug("cleaning existing path") |
6d49fae517ba
pages: browser metadata + root `_browser`:
Goffi <goffi@goffi.org>
parents:
1250
diff
changeset
|
136 shutil.rmtree(page_dyn_path) |
1247 | 137 |
1253
6d49fae517ba
pages: browser metadata + root `_browser`:
Goffi <goffi@goffi.org>
parents:
1250
diff
changeset
|
138 page_dyn_path.mkdir(parents=True, exist_ok=True) |
6d49fae517ba
pages: browser metadata + root `_browser`:
Goffi <goffi@goffi.org>
parents:
1250
diff
changeset
|
139 log.debug("copying browser python files") |
1503
2796e73ed50c
tasks (brython): fix brython scripts loading.
Goffi <goffi@goffi.org>
parents:
1384
diff
changeset
|
140 self.copy_files(dyn_data['path'].iterdir(), page_dyn_path) |
1247 | 141 |
1268
e628724530ec
pages, tasks (brython): use set for scripts + common template data:
Goffi <goffi@goffi.org>
parents:
1262
diff
changeset
|
142 script = Script( |
e628724530ec
pages, tasks (brython): use set for scripts + common template data:
Goffi <goffi@goffi.org>
parents:
1262
diff
changeset
|
143 type='text/python', |
e628724530ec
pages, tasks (brython): use set for scripts + common template data:
Goffi <goffi@goffi.org>
parents:
1262
diff
changeset
|
144 src=f"/{C.BUILD_DIR}/{C.BUILD_DIR_DYN}/{url_hash}/__init__.py" |
e628724530ec
pages, tasks (brython): use set for scripts + common template data:
Goffi <goffi@goffi.org>
parents:
1262
diff
changeset
|
145 ) |
1384
b61509c47cac
tasks (brython): fixed Brython scripts during dev mode reload
Goffi <goffi@goffi.org>
parents:
1335
diff
changeset
|
146 dyn_data.setdefault('scripts', utils.OrderedSet()).add(script) |