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 |
|
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) |