Mercurial > libervia-web
annotate libervia/server/tasks/implicit/task_brython.py @ 1321:eb85ef26cb4a
server: use `bulma` theme as default for default site:
`default` theme is not used for now as real default, because dev work is focusing on bulma
theme, and the default one may be broken. This should (or may not) change in the future.
author | Goffi <goffi@goffi.org> |
---|---|
date | Sat, 01 Aug 2020 16:56:04 +0200 |
parents | 0e4e413eb8db |
children | 089742e065e3 |
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 | |
1282
0e4e413eb8db
server: user new OrderedSet to handle scripts:
Goffi <goffi@goffi.org>
parents:
1279
diff
changeset
|
10 from sat.tools.common import utils |
1247 | 11 from libervia.server.constants import Const as C |
1268
e628724530ec
pages, tasks (brython): use set for scripts + common template data:
Goffi <goffi@goffi.org>
parents:
1262
diff
changeset
|
12 from libervia.server.classes import Script |
1247 | 13 from libervia.server.tasks import task |
14 | |
15 | |
16 log = getLogger(__name__) | |
17 | |
18 | |
19 class Task(task.Task): | |
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) | |
1279
2d1ceb026d0e
tasks (brython): copy and load `brython_stdlib.js`
Goffi <goffi@goffi.org>
parents:
1268
diff
changeset
|
57 shutil.copy(data_path / "brython_stdlib.js", self.build_path) |
1247 | 58 else: |
59 log.debug("Brython is already installed") | |
60 | |
61 self.WATCH_DIRS = [] | |
62 | |
63 for dyn_data in self.resource.browser_modules["brython"]: | |
64 url_hash = dyn_data['url_hash'] | |
65 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
|
66 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
|
67 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
|
68 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
|
69 ]) |
1268
e628724530ec
pages, tasks (brython): use set for scripts + common template data:
Goffi <goffi@goffi.org>
parents:
1262
diff
changeset
|
70 dyn_data.setdefault('template', {})['body_onload'] = self.getBodyOnload( |
e628724530ec
pages, tasks (brython): use set for scripts + common template data:
Goffi <goffi@goffi.org>
parents:
1262
diff
changeset
|
71 extra_path=[import_url]) |
1247 | 72 self.WATCH_DIRS.append(dyn_data['path'].resolve()) |
73 | |
1268
e628724530ec
pages, tasks (brython): use set for scripts + common template data:
Goffi <goffi@goffi.org>
parents:
1262
diff
changeset
|
74 def getBodyOnload(self, debug=True, cache=True, extra_path=None): |
e628724530ec
pages, tasks (brython): use set for scripts + common template data:
Goffi <goffi@goffi.org>
parents:
1262
diff
changeset
|
75 on_load_opts = {"pythonpath": [f"/{C.BUILD_DIR}"]} |
e628724530ec
pages, tasks (brython): use set for scripts + common template data:
Goffi <goffi@goffi.org>
parents:
1262
diff
changeset
|
76 if debug: |
e628724530ec
pages, tasks (brython): use set for scripts + common template data:
Goffi <goffi@goffi.org>
parents:
1262
diff
changeset
|
77 on_load_opts[debug] = 1 |
e628724530ec
pages, tasks (brython): use set for scripts + common template data:
Goffi <goffi@goffi.org>
parents:
1262
diff
changeset
|
78 if cache: |
e628724530ec
pages, tasks (brython): use set for scripts + common template data:
Goffi <goffi@goffi.org>
parents:
1262
diff
changeset
|
79 on_load_opts["cache"] = True |
e628724530ec
pages, tasks (brython): use set for scripts + common template data:
Goffi <goffi@goffi.org>
parents:
1262
diff
changeset
|
80 if extra_path is not None: |
e628724530ec
pages, tasks (brython): use set for scripts + common template data:
Goffi <goffi@goffi.org>
parents:
1262
diff
changeset
|
81 on_load_opts["pythonpath"].extend(extra_path) |
e628724530ec
pages, tasks (brython): use set for scripts + common template data:
Goffi <goffi@goffi.org>
parents:
1262
diff
changeset
|
82 |
e628724530ec
pages, tasks (brython): use set for scripts + common template data:
Goffi <goffi@goffi.org>
parents:
1262
diff
changeset
|
83 return f"brython({json.dumps(on_load_opts)})" |
e628724530ec
pages, tasks (brython): use set for scripts + common template data:
Goffi <goffi@goffi.org>
parents:
1262
diff
changeset
|
84 |
1253
6d49fae517ba
pages: browser metadata + root `_browser`:
Goffi <goffi@goffi.org>
parents:
1250
diff
changeset
|
85 def copyFiles(self, files_paths, dest): |
6d49fae517ba
pages: browser metadata + root `_browser`:
Goffi <goffi@goffi.org>
parents:
1250
diff
changeset
|
86 for p in files_paths: |
6d49fae517ba
pages: browser metadata + root `_browser`:
Goffi <goffi@goffi.org>
parents:
1250
diff
changeset
|
87 log.debug(f"copying {p}") |
6d49fae517ba
pages: browser metadata + root `_browser`:
Goffi <goffi@goffi.org>
parents:
1250
diff
changeset
|
88 if p.is_dir(): |
6d49fae517ba
pages: browser metadata + root `_browser`:
Goffi <goffi@goffi.org>
parents:
1250
diff
changeset
|
89 shutil.copytree(p, dest) |
6d49fae517ba
pages: browser metadata + root `_browser`:
Goffi <goffi@goffi.org>
parents:
1250
diff
changeset
|
90 else: |
6d49fae517ba
pages: browser metadata + root `_browser`:
Goffi <goffi@goffi.org>
parents:
1250
diff
changeset
|
91 shutil.copy(p, dest) |
6d49fae517ba
pages: browser metadata + root `_browser`:
Goffi <goffi@goffi.org>
parents:
1250
diff
changeset
|
92 |
1247 | 93 def start(self): |
94 dyn_path = self.build_path / C.BUILD_DIR_DYN | |
95 for dyn_data in self.resource.browser_modules["brython"]: | |
96 url_hash = dyn_data['url_hash'] | |
1253
6d49fae517ba
pages: browser metadata + root `_browser`:
Goffi <goffi@goffi.org>
parents:
1250
diff
changeset
|
97 if url_hash is None: |
6d49fae517ba
pages: browser metadata + root `_browser`:
Goffi <goffi@goffi.org>
parents:
1250
diff
changeset
|
98 # root modules |
1256
08cd652dea14
server, pages, tasks (brython): common_scripts:
Goffi <goffi@goffi.org>
parents:
1253
diff
changeset
|
99 url_prefix = dyn_data.get('url_prefix') |
08cd652dea14
server, pages, tasks (brython): common_scripts:
Goffi <goffi@goffi.org>
parents:
1253
diff
changeset
|
100 if url_prefix is None: |
08cd652dea14
server, pages, tasks (brython): common_scripts:
Goffi <goffi@goffi.org>
parents:
1253
diff
changeset
|
101 dest = self.build_path |
08cd652dea14
server, pages, tasks (brython): common_scripts:
Goffi <goffi@goffi.org>
parents:
1253
diff
changeset
|
102 init_dest_url = f"/{C.BUILD_DIR}/__init__.py" |
08cd652dea14
server, pages, tasks (brython): common_scripts:
Goffi <goffi@goffi.org>
parents:
1253
diff
changeset
|
103 else: |
08cd652dea14
server, pages, tasks (brython): common_scripts:
Goffi <goffi@goffi.org>
parents:
1253
diff
changeset
|
104 dest = self.build_path / url_prefix |
08cd652dea14
server, pages, tasks (brython): common_scripts:
Goffi <goffi@goffi.org>
parents:
1253
diff
changeset
|
105 dest.mkdir(exist_ok = True) |
08cd652dea14
server, pages, tasks (brython): common_scripts:
Goffi <goffi@goffi.org>
parents:
1253
diff
changeset
|
106 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
|
107 |
08cd652dea14
server, pages, tasks (brython): common_scripts:
Goffi <goffi@goffi.org>
parents:
1253
diff
changeset
|
108 self.copyFiles(dyn_data['path'].glob('*py'), dest) |
08cd652dea14
server, pages, tasks (brython): common_scripts:
Goffi <goffi@goffi.org>
parents:
1253
diff
changeset
|
109 |
08cd652dea14
server, pages, tasks (brython): common_scripts:
Goffi <goffi@goffi.org>
parents:
1253
diff
changeset
|
110 init_file = dyn_data['path'] / '__init__.py' |
08cd652dea14
server, pages, tasks (brython): common_scripts:
Goffi <goffi@goffi.org>
parents:
1253
diff
changeset
|
111 if init_file.is_file(): |
1282
0e4e413eb8db
server: user new OrderedSet to handle scripts:
Goffi <goffi@goffi.org>
parents:
1279
diff
changeset
|
112 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
|
113 Script(src=f"/{C.BUILD_DIR}/brython.js"), |
e628724530ec
pages, tasks (brython): use set for scripts + common template data:
Goffi <goffi@goffi.org>
parents:
1262
diff
changeset
|
114 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
|
115 ]) |
1268
e628724530ec
pages, tasks (brython): use set for scripts + common template data:
Goffi <goffi@goffi.org>
parents:
1262
diff
changeset
|
116 self.resource.dyn_data_common.setdefault( |
e628724530ec
pages, tasks (brython): use set for scripts + common template data:
Goffi <goffi@goffi.org>
parents:
1262
diff
changeset
|
117 "template", {})['body_onload'] = self.getBodyOnload() |
1253
6d49fae517ba
pages: browser metadata + root `_browser`:
Goffi <goffi@goffi.org>
parents:
1250
diff
changeset
|
118 else: |
6d49fae517ba
pages: browser metadata + root `_browser`:
Goffi <goffi@goffi.org>
parents:
1250
diff
changeset
|
119 page_dyn_path = dyn_path / url_hash |
6d49fae517ba
pages: browser metadata + root `_browser`:
Goffi <goffi@goffi.org>
parents:
1250
diff
changeset
|
120 if page_dyn_path.exists(): |
6d49fae517ba
pages: browser metadata + root `_browser`:
Goffi <goffi@goffi.org>
parents:
1250
diff
changeset
|
121 log.debug("cleaning existing path") |
6d49fae517ba
pages: browser metadata + root `_browser`:
Goffi <goffi@goffi.org>
parents:
1250
diff
changeset
|
122 shutil.rmtree(page_dyn_path) |
1247 | 123 |
1253
6d49fae517ba
pages: browser metadata + root `_browser`:
Goffi <goffi@goffi.org>
parents:
1250
diff
changeset
|
124 page_dyn_path.mkdir(parents=True, exist_ok=True) |
6d49fae517ba
pages: browser metadata + root `_browser`:
Goffi <goffi@goffi.org>
parents:
1250
diff
changeset
|
125 log.debug("copying browser python files") |
6d49fae517ba
pages: browser metadata + root `_browser`:
Goffi <goffi@goffi.org>
parents:
1250
diff
changeset
|
126 self.copyFiles(dyn_data['path'].iterdir(), page_dyn_path) |
1247 | 127 |
1268
e628724530ec
pages, tasks (brython): use set for scripts + common template data:
Goffi <goffi@goffi.org>
parents:
1262
diff
changeset
|
128 script = Script( |
e628724530ec
pages, tasks (brython): use set for scripts + common template data:
Goffi <goffi@goffi.org>
parents:
1262
diff
changeset
|
129 type='text/python', |
e628724530ec
pages, tasks (brython): use set for scripts + common template data:
Goffi <goffi@goffi.org>
parents:
1262
diff
changeset
|
130 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
|
131 ) |
e628724530ec
pages, tasks (brython): use set for scripts + common template data:
Goffi <goffi@goffi.org>
parents:
1262
diff
changeset
|
132 dyn_data['scripts'].add(script) |